# import pyglet
# import ctypes
# import win32api
# import win32gui
# import win32con
# import random

# from pyglet.gl import (
#     glActiveTexture,
#     glBindTexture,
#     glEnable,
#     glBlendFunc,
#     glDisable,
#     GL_TEXTURE0,
#     GL_TRIANGLES,
#     GL_BLEND,
#     GL_SRC_ALPHA,
#     GL_ONE_MINUS_SRC_ALPHA,
# )
# from pyglet.graphics import Group
# from pyglet.graphics.shader import Shader, ShaderProgram
# from pyglet.gl import *

# ctypes.windll.shcore.SetProcessDpiAwareness(2)

# _vertex_source = """#version 330 core
#     in vec2 position;
#     in vec3 tex_coords;
#     out vec3 texture_coords;

#     uniform WindowBlock 
#     {                       // This UBO is defined on Window creation, and available
#         mat4 projection;    // in all Shaders. You can modify these matrixes with the
#         mat4 view;          // Window.view and Window.projection properties.
#     } window;  

#     void main()
#     {
#         gl_Position = window.projection * window.view * vec4(position, 1, 1);
#         texture_coords = tex_coords;
#     }
# """

# _fragment_source = """#version 330 core
#     in vec3 texture_coords;
#     out vec4 final_colors;

#     uniform sampler2D our_texture;

#     void main()
#     {
#         final_colors = texture(our_texture, texture_coords.xy);
#     }
# """

# _fragment_source = """#version 330 core
#     in vec3 texture_coords;
#     out vec4 final_colors;

#     uniform sampler2D our_texture;

#     void main()
#     {
#         vec4 color = texture(our_texture, texture_coords.xy);
#         // final_colors = vec4(1.0 - color.rgb, color.a);
#         final_colors = vec4(0.0, 0.0, 0.0, color.a);
#     }
# """

# vert_shader = Shader(_vertex_source, 'vertex')
# frag_shader = Shader(_fragment_source, 'fragment')
# shader_program = ShaderProgram(vert_shader, frag_shader)


# class RenderGroup(Group):
#     """A Group that enables and binds a Texture and ShaderProgram.

#     RenderGroups are equal if their Texture and ShaderProgram
#     are equal.
#     """
#     def __init__(self, texture, program, order=0, parent=None):
#         """Create a RenderGroup.

#         :Parameters:
#             `texture` : `~pyglet.image.Texture`
#                 Texture to bind.
#             `program` : `~pyglet.graphics.shader.ShaderProgram`
#                 ShaderProgram to use.
#             `order` : int
#                 Change the order to render above or below other Groups.
#             `parent` : `~pyglet.graphics.Group`
#                 Parent group.
#         """
#         super().__init__(order, parent)
#         self.texture = texture
#         self.program = program

#     def set_state(self):
#         glActiveTexture(GL_TEXTURE0)
#         glBindTexture(self.texture.target, self.texture.id)
#         glEnable(GL_BLEND)
#         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
#         self.program.use()

#     def unset_state(self):
#         glDisable(GL_BLEND)

#     def __hash__(self):
#         return hash((self.texture.target, self.texture.id, self.order, self.parent, self.program))

#     def __eq__(self, other):
#         return (self.__class__ is other.__class__ and
#                 self.texture.target == other.texture.target and
#                 self.texture.id == other.texture.id and
#                 self.order == other.order and
#                 self.program == other.program and
#                 self.parent == other.parent)

# def create_quad(x, y, texture):
#     x2 = x + texture.width
#     y2 = y + texture.height
#     return x, y, x2, y, x2, y2, x, y2


# def set_window_through(hwnd, through=True):
#     ex_style = win32gui.GetWindowLong(hwnd, win32con.GWL_EXSTYLE)
#     if through:
#         new_style = ex_style | win32con.WS_EX_TRANSPARENT
#     else:
#         new_style = ex_style & ~win32con.WS_EX_TRANSPARENT

#     win32gui.SetWindowLong(
#         hwnd,
#         win32con.GWL_EXSTYLE,
#         new_style | win32con.WS_EX_LAYERED
#     )

# def set_window_borderless(hwnd):
#     win32gui.SetWindowLong(
#         hwnd, 
#         win32con.GWL_STYLE,
#         win32con.WS_VISIBLE | win32con.WS_POPUP
#     )

# def set_window_topmost(hwnd, topmost=True):
#     win32gui.SetWindowPos(
#         hwnd,
#         win32con.HWND_TOPMOST if topmost else win32con.HWND_NOTOPMOST,
#         0, 0, 0, 0,
#         win32con.SWP_NOMOVE | win32con.SWP_NOSIZE | win32con.SWP_FRAMECHANGED
#     )


# class Surface:
#     def __init__(self, window, hwnd, x, y):
#         self.window = window
#         self.hwnd = hwnd
#         self.x = x
#         self.y = y

#     def relocation(self, *args):
#         self.window.set_location(self.x, self.y)

# monitors = win32api.EnumDisplayMonitors()
# screens = pyglet.display.get_display().get_screens()
# surfaces = []
# for monitor, screen in zip(monitors, screens):
#     info = win32api.GetMonitorInfo(monitor[0])
#     width = info['Monitor'][2] - info['Monitor'][0]
#     height = info['Monitor'][3] - info['Monitor'][1]
    
#     window = pyglet.window.Window(
#         width=width,
#         height=height,
#         screen=screen,
#         style=pyglet.window.Window.WINDOW_STYLE_TRANSPARENT,
#         config=pyglet.gl.Config(
#             alpha_size=8,
#             double_buffer=True,
#             depth_size=0,
#             samples=4
#         ),
#         visible=False
#     )
#     hwnd = window._hwnd

#     wr = win32gui.GetWindowRect(hwnd)
#     cr = win32gui.GetClientRect(hwnd)
#     th = (wr[3] - wr[1]) - (cr[3] - cr[1])

#     o = th // 2
#     x = info['Monitor'][0]
#     y = info['Monitor'][1] + o - (o - 18)

#     window.set_location(x - width, y)

#     set_window_through(hwnd)
#     set_window_topmost(hwnd)

#     surface = Surface(window, hwnd, x, y)
#     surfaces.append(surface)


# # 创建FBO和纹理
# texture = GLuint(0)
# glGenTextures(1, texture)
# glBindTexture(GL_TEXTURE_2D, texture)
# glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, None)
# glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
# glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)

# fbo = GLuint(0)
# glGenFramebuffers(1, fbo)
# glBindFramebuffer(GL_FRAMEBUFFER, fbo)
# glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0)

# # 检查FBO完整性
# if glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE:
#     raise RuntimeError("Framebuffer is not complete!")

# glBindFramebuffer(GL_FRAMEBUFFER, 0)


# batch = pyglet.graphics.Batch()

# ciallo = pyglet.image.load_animation("ciallo.gif")
# # ciallo = pyglet.image.load("img.png")
# sprite = pyglet.sprite.Sprite(ciallo, batch=batch)
# sprite.x = (window.width - sprite.width) // 2
# sprite.y = (window.height - sprite.height) // 2

# # for frame in ciallo.frames:
# #     tex = frame.image.get_texture()

# # group = RenderGroup(tex, shader_program)
# # indices = (0, 1, 2, 0, 2, 3)
# # vertex_positions = create_quad(576, 296, tex)
# # vertex_list = shader_program.vertex_list_indexed(4, GL_TRIANGLES, indices, batch, group,
# #                                                  position=('f', vertex_positions),
# #                                                  tex_coords=('f', tex.tex_coords))
# # 创建全屏四边形
# vertices = [-1.0, -1.0,  1.0, -1.0,  1.0, 1.0,  -1.0, 1.0]
# tex_coords = [0.0, 0.0, 0.0,  1.0, 0.0, 0.0,  1.0, 1.0, 0.0,  0.0, 1.0, 0.0]  # vec3格式

# fullscreen_quad = shader_program.vertex_list(
#     4, GL_TRIANGLE_STRIP,
#     position=('f', vertices),
#     tex_coords=('f', tex_coords)
# )


# for surface in surfaces:
#     window = surface.window
#     hwnd = surface.hwnd

#     label = pyglet.text.Label(
#         "Ciallo～(∠・ω< )⌒★", 
#         font_size=24,
#         x=window.width,
#         y=window.height // 2,
#         anchor_x='left',
#         anchor_y='center',
#         batch=batch
#     )
#     label.color = (255, 255, 255, 255)
#     move_speed = 150

#     def update(dt):
#         label.x -= move_speed * dt

#         label.color = (
#             random.randint(0, 255),
#             random.randint(0, 255),
#             random.randint(0, 255),
#             255
#         )
        
#         if label.x + label.content_width < 0:
#             label.x = window.width

#     @window.event
#     def on_draw():
#         glBindFramebuffer(GL_FRAMEBUFFER, fbo)
#         glViewport(0, 0, width, height)
#         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

#         glEnable(GL_BLEND)
#         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)

#         # pyglet.gl.glClearColor(0.5, 0, 0, 0.5)
#         batch.draw()
#         glDisable(GL_BLEND)

#         glBindFramebuffer(GL_FRAMEBUFFER, 0)
#         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

#         glActiveTexture(GL_TEXTURE0)
#         glBindTexture(GL_TEXTURE_2D, texture)

#         shader_program.use()
#         shader_program["our_texture"] = 0
#         fullscreen_quad.draw(GL_TRIANGLE_STRIP)

#     window.set_visible(True)
#     set_window_borderless(hwnd)
#     pyglet.clock.schedule_once(surface.relocation, 0.05)
#     pyglet.clock.schedule_interval(update, 1/60.0)

# pyglet.app.run()


# import pyglet
# import ctypes
# import win32api
# import win32gui
# import win32con
# import random
# from pyglet.gl import *

# ctypes.windll.shcore.SetProcessDpiAwareness(2)

# # 创建着色器程序
# _vertex_source = """#version 330 core
#     in vec2 position;
#     in vec2 tex_coords;
#     out vec2 v_tex_coords;

#     void main()
#     {
#         gl_Position = vec4(position, 0.0, 1.0);
#         v_tex_coords = tex_coords;
#     }
# """

# _fragment_source = """#version 330 core
#     in vec2 v_tex_coords;
#     out vec4 fragColor;

#     uniform sampler2D tex;

#     void main()
#     {
#         fragColor = texture(tex, v_tex_coords);
#     }
# """

# vert_shader = pyglet.graphics.shader.Shader(_vertex_source, 'vertex')
# frag_shader = pyglet.graphics.shader.Shader(_fragment_source, 'fragment')
# shader_program = pyglet.graphics.shader.ShaderProgram(vert_shader, frag_shader)

# class Surface:
#     def __init__(self, window, hwnd, x, y):
#         self.window = window
#         self.hwnd = hwnd
#         self.x = x
#         self.y = y
#         self.batch = pyglet.graphics.Batch()
        
#         # 创建内容
#         try:
#             self.animation = pyglet.image.load_animation("ciallo.gif")
#             self.sprite = pyglet.sprite.Sprite(self.animation, batch=self.batch)
#             self.sprite.x = (window.width - self.sprite.width) // 2
#             self.sprite.y = (window.height - self.sprite.height) // 2
#         except:
#             # 创建回退内容
#             self.sprite = pyglet.shapes.Rectangle(
#                 window.width//2 - 50, window.height//2 - 50, 
#                 100, 100, 
#                 color=(255, 0, 0), 
#                 batch=self.batch
#             )
        
#         # 创建移动文本
#         self.label = pyglet.text.Label(
#             "Ciallo～(∠・ω< )⌒★", 
#             font_size=24,
#             x=window.width,
#             y=window.height // 2,
#             anchor_x='left',
#             anchor_y='center',
#             batch=self.batch
#         )
#         self.label.color = (255, 255, 255, 255)
#         self.move_speed = 150
        
#         # 1. 创建FBO和纹理
#         self.texture = GLuint(0)
#         glGenTextures(1, byref(self.texture))
#         glBindTexture(GL_TEXTURE_2D, self.texture)
#         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, window.width, window.height, 
#                      0, GL_RGBA, GL_UNSIGNED_BYTE, None)
#         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
#         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
        
#         self.fbo = GLuint(0)
#         glGenFramebuffers(1, byref(self.fbo))
#         glBindFramebuffer(GL_FRAMEBUFFER, self.fbo)
#         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 
#                                GL_TEXTURE_2D, self.texture, 0)
        
#         # 检查FBO完整性
#         status = glCheckFramebufferStatus(GL_FRAMEBUFFER)
#         if status != GL_FRAMEBUFFER_COMPLETE:
#             raise RuntimeError(f"Framebuffer not complete: {status}")
        
#         glBindFramebuffer(GL_FRAMEBUFFER, 0)
        
#         # 创建全屏四边形顶点列表
#         self.vertex_list = shader_program.vertex_list(
#             4, GL_TRIANGLE_STRIP,
#             position=('f', (-1, -1, 1, -1, -1, 1, 1, 1)),
#             tex_coords=('f', (0, 0, 1, 0, 0, 1, 1, 1))
#         )

#     def update(self, dt):
#         self.label.x -= self.move_speed * dt
#         self.label.color = (
#             random.randint(0, 255),
#             random.randint(0, 255),
#             random.randint(0, 255),
#             255
#         )
        
#         if self.label.x + self.label.content_width < 0:
#             self.label.x = self.window.width

#     def draw(self):
#         # 2. 渲染到FBO
#         glBindFramebuffer(GL_FRAMEBUFFER, self.fbo)
#         glViewport(0, 0, self.window.width, self.window.height)
        
#         glClearColor(0.0, 0.0, 0.0, 0.0)  # 透明背景
#         glClear(GL_COLOR_BUFFER_BIT)
        
#         glEnable(GL_BLEND)
#         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
#         self.batch.draw()
#         glDisable(GL_BLEND)
        
#         # 3. 渲染到窗口
#         glBindFramebuffer(GL_FRAMEBUFFER, 0)  # 绑定回默认帧缓冲区
#         glViewport(0, 0, self.window.width, self.window.height)
        
#         glClearColor(0.0, 0.0, 0.0, 0.0)  # 透明背景
#         glClear(GL_COLOR_BUFFER_BIT)
        
#         # 使用着色器程序
#         shader_program.use()
        
#         # 绑定纹理
#         glActiveTexture(GL_TEXTURE0)
#         glBindTexture(GL_TEXTURE_2D, self.texture)
#         shader_program['tex'] = 0  # 设置纹理单元
        
#         # 绘制全屏四边形
#         glEnable(GL_BLEND)
#         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
#         self.vertex_list.draw(GL_TRIANGLE_STRIP)
#         glDisable(GL_BLEND)

# def set_window_through(hwnd, through=True):
#     ex_style = win32gui.GetWindowLong(hwnd, win32con.GWL_EXSTYLE)
#     if through:
#         new_style = ex_style | win32con.WS_EX_TRANSPARENT
#     else:
#         new_style = ex_style & ~win32con.WS_EX_TRANSPARENT

#     win32gui.SetWindowLong(
#         hwnd,
#         win32con.GWL_EXSTYLE,
#         new_style | win32con.WS_EX_LAYERED
#     )

# def set_window_borderless(hwnd):
#     win32gui.SetWindowLong(
#         hwnd, 
#         win32con.GWL_STYLE,
#         win32con.WS_VISIBLE | win32con.WS_POPUP
#     )

# def set_window_topmost(hwnd, topmost=True):
#     win32gui.SetWindowPos(
#         hwnd,
#         win32con.HWND_TOPMOST if topmost else win32con.HWND_NOTOPMOST,
#         0, 0, 0, 0,
#         win32con.SWP_NOMOVE | win32con.SWP_NOSIZE | win32con.SWP_FRAMECHANGED
#     )

# # 主程序
# if __name__ == "__main__":
#     monitors = win32api.EnumDisplayMonitors()
#     screens = pyglet.display.get_display().get_screens()
#     surfaces = []

#     for monitor, screen in zip(monitors, screens):
#         info = win32api.GetMonitorInfo(monitor[0])
#         width = info['Monitor'][2] - info['Monitor'][0]
#         height = info['Monitor'][3] - info['Monitor'][1]
        
#         window = pyglet.window.Window(
#             width=width,
#             height=height,
#             screen=screen,
#             style=pyglet.window.Window.WINDOW_STYLE_BORDERLESS,
#             config=pyglet.gl.Config(
#                 alpha_size=8,
#                 double_buffer=True
#             ),
#             visible=False
#         )
#         hwnd = window._hwnd

#         # 设置窗口位置
#         x = info['Monitor'][0]
#         y = info['Monitor'][1]
#         window.set_location(x, y)

#         # 设置窗口属性
#         set_window_through(hwnd)
#         set_window_topmost(hwnd)
#         set_window_borderless(hwnd)

#         # 创建Surface对象
#         surface = Surface(window, hwnd, x, y)
#         surfaces.append(surface)
        
#         # 设置窗口事件
#         @window.event
#         def on_draw():
#             surface.draw()
        
#         # 设置定时更新
#         pyglet.clock.schedule_interval(surface.update, 1/60.0)
#         window.set_visible(True)

#     pyglet.app.run()


import pyglet
import ctypes
import win32api
import win32gui
import win32con
from pyglet.gl import *
from pyglet.graphics.shader import Shader, ShaderProgram

ctypes.windll.shcore.SetProcessDpiAwareness(2)

# 着色器代码 - 仅应用于图片
_vertex_source = """#version 330 core
    in vec2 position;
    in vec2 tex_coords;
    out vec2 texture_coords;

    void main()
    {
        gl_Position = vec4(position, 0.0, 1.0);
        texture_coords = tex_coords;
    }
"""

_fragment_source = """#version 330 core
    in vec2 texture_coords;
    out vec4 final_colors;

    uniform sampler2D our_texture;
    uniform float time;  // 时间参数用于动画效果

    void main()
    {
        vec4 color = texture(our_texture, texture_coords);
        
        // 示例效果：随时间变化的颜色反转 + 波纹效果
        float wave = sin(time * 5.0 + texture_coords.x * 10.0) * 0.05;
        vec2 distorted_coords = vec2(texture_coords.x, texture_coords.y + wave);
        vec4 distorted_color = texture(our_texture, distorted_coords);
        
        // 反转颜色 + 保留alpha
        // final_colors = vec4(1.0 - distorted_color.rgb, color.a);
        final_colors = distorted_color;
    }
"""

# # 获取主显示器信息
# monitor_info = win32api.GetMonitorInfo(win32api.EnumDisplayMonitors()[0][0])
# width = monitor_info['Monitor'][2] - monitor_info['Monitor'][0]
# height = monitor_info['Monitor'][3] - monitor_info['Monitor'][1]

# # 创建窗口
# window = pyglet.window.Window(
#     width=width,
#     height=height,
#     style=pyglet.window.Window.WINDOW_STYLE_TRANSPARENT,
#     config=pyglet.gl.Config(
#         alpha_size=8,
#         double_buffer=True,
#         depth_size=0
#     ),
#     visible=False
# )
# hwnd = window._hwnd

# # 设置窗口属性
# ex_style = win32gui.GetWindowLong(hwnd, win32con.GWL_EXSTYLE)
# new_style = ex_style | win32con.WS_EX_LAYERED | win32con.WS_EX_TRANSPARENT
# win32gui.SetWindowLong(hwnd, win32con.GWL_EXSTYLE, new_style)

# # 置顶窗口
# win32gui.SetWindowPos(
#     hwnd,
#     win32con.HWND_TOPMOST,
#     0, 0, width, height,
#     win32con.SWP_NOACTIVATE | win32con.SWP_SHOWWINDOW
# )

def set_window_through(hwnd, through=True):
    ex_style = win32gui.GetWindowLong(hwnd, win32con.GWL_EXSTYLE)
    if through:
        new_style = ex_style | win32con.WS_EX_TRANSPARENT
    else:
        new_style = ex_style & ~win32con.WS_EX_TRANSPARENT

    win32gui.SetWindowLong(
        hwnd,
        win32con.GWL_EXSTYLE,
        new_style | win32con.WS_EX_LAYERED
    )

def set_window_borderless(hwnd):
    win32gui.SetWindowLong(
        hwnd, 
        win32con.GWL_STYLE,
        win32con.WS_VISIBLE | win32con.WS_POPUP
    )

def set_window_topmost(hwnd, topmost=True):
    win32gui.SetWindowPos(
        hwnd,
        win32con.HWND_TOPMOST if topmost else win32con.HWND_NOTOPMOST,
        0, 0, 0, 0,
        win32con.SWP_NOMOVE | win32con.SWP_NOSIZE | win32con.SWP_FRAMECHANGED
    )


class Surface:
    def __init__(self, window, hwnd, x, y):
        self.window = window
        self.hwnd = hwnd
        self.x = x
        self.y = y

    def relocation(self, *args):
        self.window.set_location(self.x, self.y)

monitors = win32api.EnumDisplayMonitors()
screens = pyglet.display.get_display().get_screens()
surfaces = []
for monitor, screen in zip(monitors, screens):
    info = win32api.GetMonitorInfo(monitor[0])
    width = info['Monitor'][2] - info['Monitor'][0]
    height = info['Monitor'][3] - info['Monitor'][1]
    
    window = pyglet.window.Window(
        width=width,
        height=height,
        screen=screen,
        style=pyglet.window.Window.WINDOW_STYLE_TRANSPARENT,
        config=pyglet.gl.Config(
            alpha_size=8,
            double_buffer=True,
            depth_size=0,
            samples=4
        ),
        visible=False
    )
    hwnd = window._hwnd

    wr = win32gui.GetWindowRect(hwnd)
    cr = win32gui.GetClientRect(hwnd)
    th = (wr[3] - wr[1]) - (cr[3] - cr[1])

    o = th // 2
    x = info['Monitor'][0]
    y = info['Monitor'][1] + o - (o - 18)

    window.set_location(x - width, y)

    set_window_through(hwnd)
    set_window_topmost(hwnd)

    surface = Surface(window, hwnd, x, y)
    surfaces.append(surface)
window = surfaces[0].window
hwnd = surfaces[0].hwnd

# 加载图片
try:
    image = pyglet.image.load("img.png")  # 替换为您的图片路径
except:
    # 备用方案：创建测试图像
    image = pyglet.image.SolidColorImagePattern((255, 0, 0, 255)).create_image(200, 200)
    print("使用备用测试图像")

# 图片在窗口中的位置和大小
img_x = 300
img_y = 200
img_width = image.width
img_height = image.height

# 创建着色器程序
vert_shader = Shader(_vertex_source, 'vertex')
frag_shader = Shader(_fragment_source, 'fragment')
shader_program = ShaderProgram(vert_shader, frag_shader)

# 创建FBO和纹理 - 大小与图片相同
fbo = GLuint(0)
texture = GLuint(0)

glGenFramebuffers(1, fbo)
glGenTextures(1, texture)

glBindTexture(GL_TEXTURE_2D, texture)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, img_width, img_height, 0, 
             GL_RGBA, GL_UNSIGNED_BYTE, None)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)

glBindFramebuffer(GL_FRAMEBUFFER, fbo)
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 
                      GL_TEXTURE_2D, texture, 0)

if glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE:
    print("Framebuffer不完整!")
    # 尝试使用替代方法
    glBindFramebuffer(GL_FRAMEBUFFER, 0)

# 创建图片的顶点列表（用于FBO渲染）
img_vertices = [
    -1.0, -1.0,  # 左下
     1.0, -1.0,  # 右下
    -1.0,  1.0,  # 左上
     1.0,  1.0   # 右上
]

img_tex_coords = [
    0.0, 0.0,  # 左下
    1.0, 0.0,  # 右下
    0.0, 1.0,  # 左上
    1.0, 1.0   # 右上
]

img_vertex_list = shader_program.vertex_list(
    4, GL_TRIANGLE_STRIP,
    position=('f', img_vertices),
    tex_coords=('f', img_tex_coords)
)

# 创建用于在窗口上绘制纹理的顶点列表（指定位置和大小）
def create_display_vertices(x, y, width, height, win_width, win_height):
    """创建在窗口坐标系中绘制的顶点"""
    # 归一化坐标
    x1 = 2.0 * x / win_width - 1.0
    y1 = 2.0 * y / win_height - 1.0
    x2 = 2.0 * (x + width) / win_width - 1.0
    y2 = 2.0 * (y + height) / win_height - 1.0
    
    return [
        x1, y1,  # 左下
        x2, y1,  # 右下
        x1, y2,  # 左上
        x2, y2   # 右上
    ]

display_vertices = create_display_vertices(
    img_x, img_y, img_width, img_height, width, height
)

display_tex_coords = [
    0.0, 0.0,  # 左下
    1.0, 0.0,  # 右下
    0.0, 1.0,  # 左上
    1.0, 1.0   # 右上
]

# 简单的纹理显示着色器（用于在窗口上绘制FBO纹理）
simple_vertex_source = """#version 330 core
    in vec2 position;
    in vec2 tex_coords;
    out vec2 texture_coords;

    void main()
    {
        gl_Position = vec4(position, 0.0, 1.0);
        texture_coords = tex_coords;
    }
"""

simple_fragment_source = """#version 330 core
    in vec2 texture_coords;
    out vec4 final_colors;

    uniform sampler2D our_texture;

    void main()
    {
        final_colors = texture(our_texture, texture_coords);
    }
"""

simple_vert_shader = Shader(simple_vertex_source, 'vertex')
simple_frag_shader = Shader(simple_fragment_source, 'fragment')
simple_shader_program = ShaderProgram(simple_vert_shader, simple_frag_shader)

display_vertex_list = simple_shader_program.vertex_list(
    4, GL_TRIANGLE_STRIP,
    position=('f', display_vertices),
    tex_coords=('f', display_tex_coords)
)

# 时间变量用于着色器动画
time_value = 0.0

def update(dt):
    """更新着色器时间参数"""
    global time_value
    time_value += dt

@window.event
def on_draw():
    # 清除窗口为完全透明
    glClearColor(0.0, 0.0, 0.0, 0.0)
    glClear(GL_COLOR_BUFFER_BIT)
    
    # 第一步：渲染到FBO（应用特效着色器）
    glBindFramebuffer(GL_FRAMEBUFFER, fbo)
    glViewport(0, 0, img_width, img_height)
    
    # 清除FBO为透明
    glClearColor(0.0, 0.0, 0.0, 0.0)
    glClear(GL_COLOR_BUFFER_BIT)
    
    # 应用特效着色器
    shader_program.use()
    shader_program["time"] = time_value
    
    # 绑定原始图片纹理
    glActiveTexture(GL_TEXTURE0)
    glBindTexture(GL_TEXTURE_2D, image.get_texture().id)
    shader_program["our_texture"] = 0
    
    # 在FBO中绘制图片（应用着色器效果）
    glEnable(GL_BLEND)
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
    img_vertex_list.draw(GL_TRIANGLE_STRIP)
    glDisable(GL_BLEND)
    
    # 第二步：回到默认帧缓冲
    glBindFramebuffer(GL_FRAMEBUFFER, 0)
    glViewport(0, 0, width, height)
    
    # 第三步：在窗口上绘制处理后的纹理
    simple_shader_program.use()
    
    # 绑定FBO纹理
    glActiveTexture(GL_TEXTURE0)
    glBindTexture(GL_TEXTURE_2D, texture)
    simple_shader_program["our_texture"] = 0
    
    # 在指定位置绘制处理后的图片
    glEnable(GL_BLEND)
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
    display_vertex_list.draw(GL_TRIANGLE_STRIP)
    glDisable(GL_BLEND)

# 启动应用
window.set_visible(True)
set_window_borderless(hwnd)
pyglet.clock.schedule_once(surface.relocation, 0.05)
pyglet.clock.schedule_interval(update, 1/60.0)
pyglet.app.run()